﻿using WebServices;
using WebServices.Models;
using WebServices.Responses;
using FlightTicketDb;
using FlightTicketModel;
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web;
using System.Web.Http;
using FlightTicketContract;
using HttpTaskDbContext;
using System.Text;
using CommonUtl;
using System.Net;
using System.Text.RegularExpressions;
using System.Net.NetworkInformation;
using System.Runtime.Serialization;
using System.Web.Http.Results;
using WebServices.WebServices.Requests;
using HttpTaskModel;

namespace FlightTicketApi.Controllers.FlithTicket
{
    //[Authorize]
    [RoutePrefix("apir/FlightTicket")]
    public class FlightTicketController : ApiController, IFlightTicket, IAirline
    {
        ReaderWriterLockSlim datapro = new ReaderWriterLockSlim();
        //static List<IResponseCallback> subscribers = new List<IResponseCallback>();
        //private IResponseCallback _callback;
        private ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);


        [ActionName("AddPriceModel")]
        public ResponseBoolBase AddPriceModel(List<FlightTicketPrice> list)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                db.FlightTicketPrice.AddRange(list);
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("AddTask", ex);
            }
            return obj;
        }

        [ActionName("AddTask")]
        [HttpPost]
        public ResponseBoolBase AddTask(FlightTicketTaskRequest request)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                FlightTicketTask tsk = new FlightTicketTask() { AirCode1 = request.AirCode1, AirCode2 = request.AirCode2, AirCode3 = request.AirCode3, AirlineID = request.AirlineID, AirLineType = request.AirLineType, CreateTime = DateTime.Now, date1 = (request.date11.Value), date2 = (request.date22), Key = Guid.NewGuid(), IsEnable = true };

                DateTime dt = request.date11.Value;
                while (dt <= request.date22)
                {
                    var o = new FlightTicketChildTask()
                    {
                        AirCode1 = request.AirCode1,
                        AirCode2 = request.AirCode2,
                        AirCode3 = request.AirCode3,
                        AirlineId = request.AirlineID,
                        AirLineType = request.AirLineType,
                        CreateTime = DateTime.Now
                    ,
                        date1 = dt
                    //, date2 = (request.date22)
                    ,
                        Key = tsk.Key,
                        IsEnable = true
                    };
                    if (request.AirLineType == AirLineType.Return)
                    { o.date2 = o.date1.AddDays(3); }
                    tsk.Tasks.Add(o);
                    dt = dt.AddDays(1);
                }
                db.FlightTicketTask.Add(tsk);
                int i = db.SaveChanges();
                if (i == 0)
                {
                    obj.error = "添加任务失败";
                    obj.IsSuccess = false;
                }
                else obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("AddTask", ex, request);
            }
            return obj;
        }

        [ActionName("GetFlightTicketChildTask")]
        [HttpPost]
        public ResponsePageDataBase<FlightTicketChildTask> GetFlightTicketChildTask(FlightTicketTaskRequest req)
        {
            ResponsePageDataBase<FlightTicketChildTask> obj = new ResponsePageDataBase<FlightTicketChildTask>();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                var o = db.FlightTicketChildTask.Where(x => x.date1 >= req.date11 && x.date1 <= req.date22 && (req.AirLineType == AirLineType.None) ? x.AirLineType != AirLineType.None : x.AirLineType == req.AirLineType && req.Status == 0 ? x.TaskStatus >= 0 : x.TaskStatus == req.Status && req.AirlineID == 0 ? x.AirlineId >= 0 : x.AirlineId == req.AirlineID).OrderBy(x => x.Id).Skip((req.PageIndex - 1) * req.PageSize).Take(req.PageSize).ToList();
                obj.data.AddRange(o);
                obj.Count = db.FlightTicketChildTask.Where(x => x.date1 >= req.date11 && x.date1 <= req.date22 && (req.AirLineType == AirLineType.None) ? x.AirLineType != AirLineType.None : x.AirLineType == req.AirLineType && req.Status == 0 ? x.TaskStatus >= 0 : x.TaskStatus == req.Status && req.AirlineID == 0 ? x.AirlineId >= 0 : x.AirlineId == req.AirlineID).Count();
                obj.PageCount = 0;
                if (obj.Count % req.PageSize > 0)
                    obj.PageCount = obj.PageCount + 1;
            }
            catch (Exception ex)
            {
                obj = ResponseBase.GetResponseByException<ResponsePageDataBase<FlightTicketChildTask>>(ex);
                logger.ErrorFormat("GetFlightTicketChildTask", ex, req);
            }
            return obj;
        }

        [HttpPost]
        public ResponsePageDataBase<FlightTicketPrice> GetFlightTicketPrice(FlightTicketTaskRequest req)
        {
            ResponsePageDataBase<FlightTicketPrice> obj = new ResponsePageDataBase<FlightTicketPrice>();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                var o = db.FlightTicketPrice.Where(x => x.date1 >= req.date11 && x.date1 <= req.date22 && (req.AirLineType == AirLineType.None) ? x.AirLineType != AirLineType.None : x.AirLineType == req.AirLineType && req.Status == 0 ? x.TaskStatus >= 0 : x.TaskStatus == req.Status && req.AirlineID == 0 ? x.AirlineID >= 0 : x.AirlineID == req.AirlineID).Skip((req.PageIndex - 1) * req.PageSize).Take(req.PageSize).ToList();
                obj.data.AddRange(o);
                obj.Count = db.FlightTicketPrice.Where(x => x.date1 >= req.date11 && x.date1 <= req.date22 && (req.AirLineType == AirLineType.None) ? x.AirLineType != AirLineType.None : x.AirLineType == req.AirLineType && req.Status == 0 ? x.TaskStatus >= 0 : x.TaskStatus == req.Status && req.AirlineID == 0 ? x.AirlineID >= 0 : x.AirlineID == req.AirlineID).Count();
                obj.PageCount = 0;
                if (obj.Count % req.PageSize > 0)
                    obj.PageCount = obj.PageCount + 1;
            }
            catch (Exception ex)
            {
                obj = ResponseBase.GetResponseByException<ResponsePageDataBase<FlightTicketPrice>>(ex);
                logger.ErrorFormat("FlightTicketPrice", ex, req);
            }
            return obj;
        }

        [HttpGet]
        public ResponsePageDataBase<FlightTicketChildTask> GetSpiderTask(string ip, int count)
        {
            ResponsePageDataBase<FlightTicketChildTask> obj = new ResponsePageDataBase<FlightTicketChildTask>();
            try
            {
                datapro.EnterReadLock();
                FlightTicketDbContext db = new FlightTicketDbContext();
                HttpTaskDBContext db2 = new HttpTaskDBContext();
                //不可用服务器
                var enable = db2.TerminalDomainServer.Where(x => x.TerminalServer.IP == ip && x.IsEnable == false).ToList();
                //var tsk = db.FlightTicketChildTask.Where(x => x.TaskStatus == FlightTicketModel.TaskStatus.Ready).ToList();
                //var tsk = db.FlightTicketChildTask.ToList();
                //tsk = tsk.FindAll(x => enable.FindAll(s => s.DomainConfig.Domain == x.Airline.Domain).Count == 0).Take(count).ToList();
                //&& enable.FirstOrDefault(c =>
                //                    c.DomainConfig.Domain.Contains(x.Airline.Domain)) == null).ToList();
                var tsk = db.FlightTicketChildTask.Include("Airline").Where(x => x.TaskStatus == FlightTicketModel.TaskStatus.Ready).ToList();
                //&& enable.FirstOrDefault(c =>
                //                    c.DomainConfig.Domain.Contains(x.Airline.Domain)) == null).ToList();
                obj.data.AddRange(tsk);
                if (tsk.Any())
                {
                    StringBuilder sql = new StringBuilder($"UPDATE FlightTicket.dbo.FlightTicketChildTasks SET TASKSTATUS={(int)FlightTicketModel.TaskStatus.ServerSent} WHERE ID IN (");
                    foreach (var item in tsk)
                    {
                        sql.Append(item.Id + ",");
                    }
                    string sqld = sql.ToString().Trim(',') + ")";
                    //var re = DbHelperSQL.ExecuteSql(sqld);
                }
            }
            catch (Exception ex)
            {
                obj = ResponseBase.GetResponseByException<ResponsePageDataBase<FlightTicketChildTask>>(ex);
                logger.ErrorFormat("GetSpiderTask", ex, ip);
            }
            finally
            {
                datapro.ExitReadLock();
            }
            logger.InfoFormat("取出数据");
            return obj;
        }

        #region IAirline

        [ActionName("GetAirline")]
        [HttpGet]
        public ResponseDataBase<Airline> GetAirline()
        {
            ResponseDataBase<Airline> obj = new ResponseDataBase<Airline>();
            try
            {
                logger.InfoFormat("just for test action GetAirline");
                FlightTicketDbContext db = new FlightTicketDbContext();
                var o = db.Airline.Include("AirlineCounts").Where(x => x.IsDelete == 0).ToList();
                obj.data.AddRange(o);
            }
            catch (Exception ex)
            {
                obj = ResponseBase.GetResponseByException<ResponseDataBase<Airline>>(ex);
                logger.ErrorFormat("GetAirline", ex);
            }
            return obj;
        }
        [ActionName("GetAirline2")]
        [HttpGet]
        public string GetAriline2()
        {
            var r = GetAirline();
            string rr = r.ToJsonString();
            return rr;
        }
        [HttpPost]
        public ResponseBoolBase AddAirline(string AirlineName, string Url, string domain)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                Airline o = new Airline() { Key = Guid.NewGuid(), AirlineName = AirlineName, CreateTime = DateTime.Now, Domain = domain, Url = Url };

                db.Airline.Add(o);
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("AddTask", ex);
            }
            return obj;
        }
        [HttpPost]
        public ResponseBoolBase AddAirlineAccount(long id, string uname, string pwd)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                AirlineAccount o = new AirlineAccount() { ArilineId = id, CreateTime = DateTime.Now, pwd = pwd, username = uname };
                db.AirlineCount.Add(o);
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("AddAirlineAccount", ex);
            }
            return obj;
        }

        [HttpPost]
        public ResponseBoolBase SaveAirline(long id, string AirlineName, string Url, string domain)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                var o = db.Airline.Find(id);
                o.AirlineName = AirlineName;
                o.Url = Url;
                o.Domain = domain;
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("SaveAirline", ex);
            }
            return obj;
        }

        [HttpPost]
        public ResponseBoolBase SaveAirlineAccount(long id, string uname, string pwd)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();

                var o = db.AirlineCount.Find(id);
                o.username = uname;
                o.pwd = pwd;
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("AddTask", ex);
            }
            return obj;
        }
        #endregion

        #region Net
        public string NetIP()
        {
            try
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.Default;
                //string response = client.DownloadString("http://1212.ip138.com/ic.asp");//失效了
                string response = client.DownloadString("http://icanhazip.com/");//可用，可能不稳定
                                                                                 //string response = client.DownloadString("http://ip.chinaz.com/");//站长之家
                string myReg = @"((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))";
                Match mc = Regex.Match(response, myReg, RegexOptions.Singleline);
                if (mc.Success && mc.Groups.Count > 1)
                {
                    response = mc.Value;
                    return response;
                }
                else
                {
                    Console.WriteLine("Can't get you Ip address!");
                    return "Can't get you Ip address!";
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Can't get you Ip address! " + e.ToString());
                return "Can't get you Ip address!";
            }
        }
        public string NetPPPOEIP()
        {
            int timeout = 10000;
            int i = timeout * 2;
            while (i > 0)
            {
                try
                {
                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                    bool havePPPOE = false;
                    foreach (NetworkInterface adapter in nics)
                    {
                        if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ppp)
                        {
                            havePPPOE = true;
                            IPInterfaceProperties ip = adapter.GetIPProperties();     //IP配置信息
                            if (ip.UnicastAddresses.Count > 0)
                            {
                                return ip.UnicastAddresses[0].Address.ToString();
                            }
                        }
                    }
                    //当没有宽带连接的时候直接返回空
                    if (!havePPPOE) return "";
                }
                catch (Exception ex)
                {
                    Console.WriteLine("获取宽带拨号IP出错:" + ex.Message);
                }
                i--;
                Thread.Sleep(500);
            }
            return "";

        }

        public ResponseBoolBase ForbiddenIP(string ip, string domain)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                using (HttpTaskDBContext db = new HttpTaskDBContext())
                {
                    #region MyRegion
                    var dom = db.TerminalDomainServer.FirstOrDefault(x => x.DomainConfig != null && x.TerminalServer != null && x.TerminalServer.IP.Trim() == ip.Trim() && domain.Trim() == x.DomainConfig.Domain.Trim());
                    if (dom == null)
                    {
                        var ipp = db.TerminalServer.FirstOrDefault(x => x.IP.Trim() == ip.Trim() && x.IsDelete == false);
                        if (ipp == null)
                        {
                            ipp = new TerminalServer() { IP = ip.Trim(), Port = 0, Key = Guid.NewGuid(), CreatedTime = DateTime.Now };
                            ipp = db.TerminalServer.Add(ipp);
                            db.SaveChanges();
                        }
                        var d = db.DomainConfig.FirstOrDefault(x => x.Domain.Trim() == domain.Trim() && x.IsDelete == false);
                        if (d == null)
                        {
                            d = new DomainConfig() { IsDelete = false, CreatedTime = DateTime.Now, Domain = domain, Key = Guid.NewGuid() };
                            d = db.DomainConfig.Add(d);
                            db.SaveChanges();
                        }

                        TerminalDomainServer ds = new TerminalDomainServer() { DomainConfigId = d.Id, ForbiddenTime = DateTime.Now, ForbiddenTimeOut = 20, TerminalServerId = ipp.Id, IsEnable = false };
                        db.SaveChanges();
                    }
                    else
                    {
                        dom.IsEnable = false;
                        db.SaveChanges();
                    }
                    #endregion
                }
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("设置封禁IP失败", ex);
            }
            return obj;
        }

        public ResponseBoolBase UpdateTasksStatus(RequestStatus request)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                var tsks = db.FlightTicketChildTask.Where(x => request.ids.Contains(x.Id)).ToList();
                tsks.ForEach(x => x.TaskStatus = request.Status);
                db.SaveChanges();
                obj.IsSuccess = true;
                logger.InfoFormat("更新状态成功");
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("更新状态失败", ex);
            }
            finally
            { }
            return obj;
        }



        public ResponseBoolBase UpdateTaskStatus(long id, FlightTicketModel.TaskStatus status)
        {
            ResponseBoolBase obj = new ResponseBoolBase();
            try
            {
                FlightTicketDbContext db = new FlightTicketDbContext();
                var tsks = db.FlightTicketChildTask.Find(id);
                tsks.TaskStatus = status;
                db.SaveChanges();
                obj.IsSuccess = true;
            }
            catch (Exception ex)
            {
                obj.IsSuccess = false;
                obj = ResponseBase.GetResponseByException<ResponseBoolBase>(ex);
                logger.ErrorFormat("更新状态失败", ex);
            }
            finally
            { }
            return obj;
            return obj;
        }
        #endregion

    }
}